package com.xhj.mybatis.reflection.invoker;

import com.xhj.mybatis.reflection.Reflector;

import java.lang.reflect.Field;

/**
 * GetFieldInvoker
 *
 * @author XJks
 * @description 用于通过反射获取对象字段值的调用器
 */
public class GetFieldInvoker implements Invoker {
    /**
     * 用于保存需要访问的字段对象
     */
    private final Field field;

    /**
     * 构造方法，接收一个 Field 对象并赋值给成员变量
     *
     * @param field 需要访问的字段
     */
    public GetFieldInvoker(Field field) {
        this.field = field;
    }

    /**
     * 实现 Invoker 接口的 invoke 方法，用于获取目标对象指定字段的值
     *
     * @param target 表示要调用方法的对象
     * @param args   参数 args 表示调用方法时传递的参数数组
     * @return 返回字段的值
     * @throws IllegalAccessException
     */
    @Override
    public Object invoke(Object target, Object[] args) throws IllegalAccessException {
        try {
            // 尝试直接通过反射获取 target 对象的 field 字段的值
            return field.get(target);
        } catch (IllegalAccessException e) {
            // 如果没有访问权限，捕获异常
            if (Reflector.canControlMemberAccessible()) {
                // 如果可以修改字段的可访问性，则设置为可访问
                field.setAccessible(true);
                // 再次尝试获取字段的值
                return field.get(target);
            } else {
                // 如果不能修改可访问性，则抛出异常
                throw e;
            }
        }
    }

    /**
     * 实现 Invoker 接口的 getType 方法，返回字段的类型
     *
     * @return 字段的类型
     */
    @Override
    public Class<?> getType() {
        return field.getType();
    }
}
